#ifndef LINK_QUEUE_HPP
#define LINK_QUEUE_HPP

#include "MasterQueue.hpp"
#include <cstddef>
#include <cstdlib>
#include <iostream>


typedef int QElemType;

typedef struct QNode {
    QElemType data;
    struct QNode* next;
} QNode, *QueuePtr;

typedef struct
{
    QueuePtr front;
    QueuePtr rear;
} LinkQueue;

class LinkQueueC : public MasterQueue<LinkQueue, QElemType> {
public:

    Status initQueue(LinkQueue& q) override
    {
        q.front = q.rear = new QNode;
        q.front->next = nullptr;
        return Status::Ok;
    }

    Status destoryQueue(LinkQueue& q) override
    {
        while (q.front)
        {
            QueuePtr temp = q.front;
            q.front = q.front->next;
            delete temp;
        }
        q.rear = nullptr;
        return Status::Ok;
    }

    Status clearQueue(LinkQueue& q) override
    {
        while (q.front != q.rear) {
            QueuePtr temp = q.front;
            q.front = q.front->next;
            temp->next = nullptr;
            temp->data = {};
        }
        return Status::Ok;
    }

    inline bool queueEmpty(const LinkQueue& q) override {
        return !q.front || q.front->next == nullptr;    
    }

    int queueLength(const LinkQueue& q) override {
        QueuePtr temp = q.front;
        int len;
        for (len = 1; temp != q.rear; len++){
            temp = temp->next;
        }
        return len;
    }

    QElemType getHead(LinkQueue& q) override
    {
        if (q.front != nullptr){
            return q.front->data;
        }
        return {};
    }

    Status enQueue(LinkQueue& q, QElemType e) override
    {
        QueuePtr temp = new QNode;
        temp->next = nullptr;
        q.rear->data = e;
        q.rear->next = temp;
        q.rear = temp;
        return Status::Ok;
    }

    Status deQueue(LinkQueue& q, QElemType& e) override
    {
        if (q.front == nullptr) {
            return Status::Err;
        }
        QueuePtr temp = q.front;
        e = q.front->data;
        q.front = q.front->next;
        delete temp;
        return Status::Ok;
    }

    Status queueTraverse(const LinkQueue q) override
    {
        if (q.front == nullptr) {
            return Status::Err;
        }
        while (q.front != q.rear) {
            std::cout << q.front->data << " " << std::endl; 
        }
        return Status::Ok;
    }
};

#endif
